#### deco parser, Bratislava sept 2002
################ PRAGMA DEFINITIONS ###############################
# aps 
# bas B1 B2
# chps CH LW {PSmacro}
# endobj
# nsta S_1 S_-1
# nu NU
# obj OBJECT_NAME
# ops TYPE [PTHSTART] LW {PSmacro}
# orb B1 B2 x y z CH
# pat ssssssssss
# pat3 ssssssssss
# psta S1 .. SN
# psta3 S1 .. SN
# pth P1 .. PN
# sb 5FOLD MIRROR SCREW
# sba CH1 .. CHN
# tdfix RHO
# tham E
# use OBJECT_NAME
# const CONST
#########  old-style special characters ###########################
# =    object definition
# <    orbit definition
# +    orbit symmetry breaking
# !    3d-object definition
###################################################################
# file INPUT/MKDECO/bc.inp has been cat to .bcinp by `mkdeco'
BEGIN{  # options
  instdef=-100; # this is "-ttvl" in common.p
  ronames=0;
  ndefsubtau=10;
  def3d=0;
  init3d=1;
  objdefined=0;
  dbfile=2;
  fn=ENVIRON["DECAHOME"]"/SRC/CHTAB";
  while(getline<fn){
    sch[$1]=$4;
    chs[tolower($4)]=$1;
  }close(fn);
  chs["vac"]=0;
  STDE="/dev/stderr";
#  print ARGC,ARGV[1],ARGV[2],ARGV[3],ARGV[4];
#  exit;
  dpmodel=ARGV[ARGC-1];
  delete ARGV[ARGC-1];
  ARGC--;
  if(ARGV[ARGC-1]=="-q"){# last cmdline argument
    query=1; qq=0;
    delete ARGV[ARGC-1];
    ARGC--;
  }
  if(ARGV[ARGC-2]=="-qq"){#last two cmdline arguments
    query=1; qq=1; qobj=ARGV[ARGC-1];
    delete ARGV[ARGC-1];
    ARGC--;
    delete ARGV[ARGC-1];
    ARGC--;
  }
  if(ARGV[ARGC-2]=="-c"){
      colorfile=ARGC-2;
      ARGV[ARGC-2]=ARGV[ARGC-1];
      ARGC--;
      if(colorfile==2){dbfile=0};
  }
#  print "after_begin : argc="ARGC>STDE;
  if(ARGC==2){dbfile=0};
#  print "BEG: ",colorfile,dbfile,ARGV[1],ARGV[2]>STDE;
}
ARGIND==dbfile&&FNR==1{
  nobj_save=nobj;
# check no two objects have equal names
  for(i=1;i<nobj;i++){
    for(j=i+1;j<+nobj;j++){
      if(oname[i]==oname[j]){emsg="Error: objects "i" and "j" have the same name "oname[i]", line "FNR".";exit}
    }
  }
}
$0~/^ *\\?/{ #check for backslashed keywords ## MODIF: no need for backslash
#  print "FOUND KEYWORD!";
#  i=index($0,"\\"); # there may be some spaces before the backslash
#  line=substr($0,i+1);
  sub(/^ *\\/,"",$0); # remove possible backslash
  sub(/^ */,"",$0); # remove possible spaces
  sub(/\#.*$/,"",$0); # remove comment
  line=$0;
  nw=split($0,words," ");
#  print line >> "DEBUG";
#  print "words[1] = "words[1] >> "DEBUG";
#  print "words",nw,words[1],"X_"line"_X" > "/dev/stderr";
  if(words[1]=="read_orbit_names"){ronames=1};
  if(words[1]=="auto_double"){adouble=1};
  if(tolower(words[1])=="autodouble"){
    emsg="Spelling of this option is auto_double."; exit;
  }
  if(words[1]=="const"){
    bcdef="";
    for(i=2;i<=NF;i++){bcdef=bcdef""$i};
    print bcdef >> ".bcinp";
    fflush(".bcinp");
  }
  if((words[1]=="sb")&&objdefined){
    if(!fla[nobj]){fla[nobj]=words[2]" "words[3]" "words[4]};
#    print "obj_fla=",fla[nobj];
  }
  if(words[1]=="use"){
    copy[oname[nobj]]=words[2];
#    print oname[nobj],copy[oname[nobj]];
  };
  if(words[1]=="sba"&&objdefined){
    omu=nw-1;
    osb[nobj,norb[nobj]]=omu"  "substr(line,4);
#    print "orb_sb=",osb[nobj,norb[nobj]] > "/dev/stderr";
  }
  if(words[1]=="obj"){
    objdefined=1;
    if(ARGIND==dbfile){
#      print "DBFILE="ARGIND,line,opo[words[2]],nobj,nobj_save > STDE;
      if(opo[words[2]]){nobj=opo[words[2]]}else{nobj=0};
    }else{
      nobj++;
      ocolor[nobj]=1;
      autocc[nobj]=0;
      opo[words[2]]=nobj;
#      print "DECOFILE="ARGIND,oname[nobj],nobj,nobj_save > STDE;
    };
    oname[nobj]=words[2];
    name2i[words[2]]=nobj;
#    print "NOW nobj="nobj" ocolor="ocolor[nobj] >> "DEBUG";

#    if(!nstadef[nobj]){
#	print "objdef, redef nsta: ",ARGIND,oname[nobj]>STDE;
#	nsta[nobj,-1]=1;
#	nsta[nobj,1]=1;
#    }

#    nu[nobj]="undef";
#    bas[nobj]="undef";
#    pat[nobj]="undef";
#    pth[nobj]="0";
#    fla[nobj]="0 0 0";
  }
  if(words[1]=="ops"&&objdefined){
# NOTE: nobj is set to 0 for dbfile, if object was not required
    if(ARGIND==1||(ARGIND==dbfile&&nobj)){
      ops[oname[nobj]]=substr(line,5);
      opsdefs++;
      print "OPSDEF "opsdefs" "oname[nobj] > "/dev/stderr";
      new_style=1;
    };
  };
  if(words[1]=="aps"&&objdefined&&orbdefined){
    aps[nobj,norb[nobj]]=substr(line,5);
#    print "APS0 ",nobj,norb[nobj],aps[nobj,norb[nobj]] > STDE;
    apsdefs++;
    new_style=1;
  }
  if(words[1]=="chps"){
    chdefs=1;
    if(!chps[words[2]]){chps[words[2]]=substr(line,6)};
    new_style=1;
  }
  if(words[1]=="tham"&&objdefined){
    thdef=1;
    ene[nobj]=words[2];
    new_style=1;
  }
  if(words[1]=="tdfix"&&objdefined){
    atdfix[nobj]=1;
    tdens[nobj]=words[2];
    new_style=1;
  }
  if(words[1]=="nu"&&objdefined){
#   print oname[nobj],words[2]>STDE;  
    if(!nu[nobj]){nu[nobj]=words[2]};
  }
  if(words[1]=="instance"&&objdefined){
    if(!nu2[nobj]){
      nu2[nobj]=inst(words[2]);
    };
  }
  if(words[1]=="newcolor"&&objdefined){
    ocolor[nobj]++;
#    print "OCOLOR "nobj,oname[nobj],ocolor[nobj] > "DEBUG";
  }
  if(words[1]=="node_inst"&&objdefined){
    sub(/^node_inst /,"",line);
    sub(/ *\#.*$/,"",line);
    gsub(","," ",line);
    nonu[nobj]=split(line,a);
    gsub(/x/,instdef,line);
    gsub(/X/,instdef,line);
    onu[nobj]=line;
    print "FLIPINSTNU "onu[nobj] > "/dev/stderr";
  }
  if(words[1]=="pat"&&!pat[nobj]&&objdefined){
    split(words[2],p,"");
    pat[nobj]="";
    for(k=1;k<=10;k++){pat[nobj]=pat[nobj]sprintf("%i ",p[k])};
    new_style=1;
  }
  if(words[1]=="gpat"&&!pat[nobj]&&objdefined){
    n=split(words[2],p,",");
    if(n!=10){
      emsg="Bad general pattern definition gpat at line "FNR"."; exit;
    }
    gsub(/,/," ",words[2]);
    gsub(/x/,instdef,words[2]);
    gsub(/X/,instdef,words[2]);
    pat[nobj]=words[2];
    new_style=1;
  }
  if(words[1]=="inbound_inst"&&objdefined){
    gsub(/x/,instdef,words[2]);
    gsub(/X/,instdef,words[2]);
    gsub(/,/," ",words[2]);
    n=split(words[2],p);
    ipthrec[nobj]=n"  "words[2];
    new_style=1;
  }
  if(words[1]=="pat_inst"&&pat[nobj]&&objdefined){
    n=split(words[3],p,",");
    if(n!=10){
      emsg="Bad pattern-instance definition pat_inst at line "FNR"."; exit;
    }
    nipat[nobj]++;
#    print "XXXXX", nobj,nipat[nobj] > "/dev/stderr";
    gsub(/,/," ",words[3]);
    gsub(/x/,instdef,words[3]);
    gsub(/X/,instdef,words[3]);
    sub(/x/,instdef,words[2]);
    sub(/X/,instdef,words[2]);
    ipat[nobj,nipat[nobj]]=words[2]"  "words[3];
    new_style=1;
  }
  if(words[1]=="pat3"&&objdefined){
    def3d=1;
    if(length(words[2])!=10||length(words[3])!=10){emsg="Object "oname[nobj]": invalid 3d pattern definition, line "FNR" "length(words[2])" "length(words[3]);exit};
    split(words[2],p,"");
    spat="";for(k=1;k<=10;k++){spat=spat""sprintf("%1i ",p[k])};
    pat3[nobj,-1]=spat;
    split(words[3],p,"");
    spat="";for(k=1;k<=10;k++){spat=spat""sprintf("%1i ",p[k])};
    pat3[nobj,1]=spat;
    new_style=1;
  }
  if(words[1]=="bas"&&!bas[nobj]&&objdefined){
    bas[nobj]=words[2]" "words[3];
#    print "BAS ",nobj,bas[nobj] > STDE;
    new_style=1;
  }
  if(words[1]=="autocenter"&&objdefined){
    autocc[nobj]=1;
    new_style=1;
  }  
  if(words[1]=="pth"&&!pth[nobj]&&objdefined){
    npth[nobj]=nw-1;
    pth[nobj]=substr(line,5);
    new_style=1;
  }
  if(words[1]=="init3d"){
    def3d=1;
    init3d=words[2];
    if(init3d!=1&&init3d!=2){
      emsg="Bad value of init3d";
      exit;
    }
  }
  if(words[1]=="nsta"&&objdefined){
    nsta[nobj,-1]=words[2];
    nsta[nobj,1]=words[3];
#    print"nsta-def : ",nobj,oname[nobj],words[2],words[3]>STDE;
    def3d=1;
    nstadef[nobj]=1;
#    print "NSTA ",oname[nobj],def3d>STDE;
  }
  if(words[1]=="psta"&&!psta[nobj]&&objdefined){
    np=split(words[2],p,"");
    if(npth[nobj]&&np!=npth[nobj]){
      emsg="PSTA: invalid path status, line "FNR"."; exit;
    };
    sp="";for(k=1;k<=np;k++){sp=sp""sprintf("%i ",p[k])};
    psta[nobj]=sp;
    new_style=1;
  }  
  if(words[1]=="gpsta"&&!psta[nobj]&&objdefined){
    n=split(words[2],p,",");
    if(npth[nobj]&&n!=npth[nobj]){
      emsg="GPSTA: invalid general definitition of path status, line "FNR"."; exit;
    };
    gsub(/,/," ",words[2]);
    gsub(/x/,instdef,words[2]);
    gsub(/X/,instdef,words[2]);
    psta[nobj]=words[2];
    new_style=1;
  }
  if(words[1]=="psta3"&&objdefined){
    np=split(words[2],p,"");
    if(npth[nobj]&&np!=npth[nobj]){
      emsg="PSTA3: invalid 3d path status, line "FNR"."; exit;
    };
    sp3="";for(k=1;k<=np;k++){sp3=sp3""sprintf("%1i ",p[k])};
    psta3[nobj,-1]=sp3;
    np=split(words[3],p,"");
    if(npth[nobj]&&np!=npth[nobj]){
      emsg="PSTA3: invalid 3d path status, line "FNR"."; exit;
    };
    sp3="";for(k=1;k<=np;k++){sp3=sp3""sprintf("%1i ",p[k])};
    psta3[nobj,1]=sp3;
    if(!npth[nobj]){npthf[nobj]=np};
    new_style=1;
  }  
  if((words[1]=="orb")&&objdefined){
    if(thdef){
      emsg=FNR": possibly mixing tile-hamiltonian and atom-orbit definitions, line "FNR".";
      exit;
    }
    orbdef=1;
    orbdefined=1;
    norb[nobj]++;
    ntorb++;
    na=split(substr(line,5),a);
    sub_xy(a); # this handles coordinates a[3-5]
    a[6]=specie(a[6]);
    setname=""; zlevel="";
    for(i=7;i<=na;i++){
      split(a[i],as,"=");
#      print "XXX",na,as[1],as[2]>STDE;
      if(as[1]=="name"){setname=as[2]};
      if(as[1]=="zdouble"){
	emsg="This option is now now called _zlevel_";
	exit;
      }
      if(as[1]=="zlevel"){zlevel=as[2]};
      if(as[1]=="sba"){
	nw=split(as[2],bs,",");
#	gsub(/\,/," ",as[2]);
	osb[nobj,norb[nobj]]="  "nw" ";
	for(j=1;j<=nw;j++){
	  bs[j]=specie(bs[j]);
	  osb[nobj,norb[nobj]]=osb[nobj,norb[nobj]]" "bs[j];
	}
	print "-- osb ",nw,"  ",osb[nobj,norb[nobj]] > "/dev/stderr";
      };
    }
    if(adouble&&zlevel!=""){
      if(zlevel=="up"){a[5]=a[5]/2+0.5};
      if(zlevel=="here"){a[5]=a[5]/2};
      if(zlevel=="down"){a[5]=a[5]/2-0.5};
#      print "zlevel",a[5] > STDE;
    }
    adef="";for(i=1;i<=6;i++){adef=adef" "a[i]};
    if(ronames==1){
      orbname[ntorb]=a[7];
    }else if(setname!=""){
      orbname[ntorb]=setname"  "oname[nobj]"_"norb[nobj];
    }else{
      orbname[ntorb]=oname[nobj]"_"norb[nobj];
    }
    orb[nobj,norb[nobj]]=adef;
    orbclass[nobj,norb[nobj]]=ocolor[nobj];
#    print nobj,norb[nobj],ocolor[nobj] > "DEBUG";
#      norb[nobj]++;
#      orb[nobj,norb[nobj]]=substr(line,5);
    new_style=1;
    if(adouble==1&&zlevel==""){ # zlevel is explicit for whether atom being up/down
      split(adef,a);
# modify mother orbit
      a[5]=a[5]/2;
      adef=""; for(i=1;i<=6;i++){adef=adef" "a[i]};
      orb[nobj,norb[nobj]]=adef;      
      norb[nobj]++;
      ntorb++;
      a[5]=a[5]+0.5; if(a[5]>1){a[5]=a[5]-1};
      a7=a[7]; a[7]=a[7]"_";
      adef=""; for(i=1;i<=6;i++){adef=adef" "a[i]};
      orb[nobj,norb[nobj]]=adef;
      osb[nobj,norb[nobj]]=osb[nobj,norb[nobj]-1];
      orbclass[nobj,norb[nobj]]=ocolor[nobj];
      orbat[a[7]]=orbat[a7];
      if(ronames==1){
	orbname[ntorb]=a[7];
      }else if(setname!=""){
	orbname[ntorb]=setname"  "oname[nobj]"_"norb[nobj];
      }else{
	orbname[ntorb]=oname[nobj]"_"norb[nobj];
      }
    }
  }
  if(words[1]=="node"&&objdefined){
    if(thdef){
      emsg=FNR": possibly mixing tile-hamiltonian and tiling inflation, line "FNR".";
      exit;
    }
    orbdef=1;
    orbdefined=1;
    split(substr(line,5),a);
# substitution
    sub_xy(a);
    adef="";for(i=1;i<=4;i++){adef=adef" "a[i]};
# addinf fake Z coord and fake chemistry
    adef=adef"  0.0  1";
    norb[nobj]++;
    orb[nobj,norb[nobj]]=adef;
#      norb[nobj]++;
#      orb[nobj,norb[nobj]]=substr(line,5);
    new_style=1;
  }
  if(words[1]=="abnode"&&objdefined){
    if(thdef){
      emsg=FNR": possibly mixing tile-hamiltonian and tiling inflation, line "FNR".";
      exit;
    }
    orbdef=1;
    orbdefined=1;
    split(substr(line,5),b);
    a[1]=b[1];
    a[2]=b[2];
    a[3]=b[3]+b[4]*tau;
    a[4]=b[5]+b[6]*tau;
    adef="";for(i=1;i<=4;i++){adef=adef" "a[i]};
# addinf fake Z coord and fake chemistry
    adef=adef"  0.0  1";
    norb[nobj]++;
    orb[nobj,norb[nobj]]=adef;
#      norb[nobj]++;
#      orb[nobj,norb[nobj]]=substr(line,5);
    new_style=1;
  }
  if(words[1]=="endobj"){
    objdefined=0;
    orbdefined=0;
    new_style=1;
  }
}
## old-style orbit-sym-break
$0~/^\+/{
  osb[nobj,norb[nobj]+1]=substr($0,2); # note: this is ADVANCE-DEFINITION FOR NEXT COMING ORBIT (unlike the new-style \sba option)!
#  print "old-style orb_sb=",osb[nobj,norb[nobj]+1];
# logical words
  nw=split(osb[nobj,norb[nobj]+1],a);
  if(nw<a[1]+1){
    emsg=FNR": old-style orb_sb: too few words.";
    exit;
  }
  old_style=1;
}
## OLDSTYLE 3D object definition
$0~/^\!/{
  line=substr($0,2);
  nw=split(line,a);
  if(a[1]!=0){
    def3d=1;
    nsta[nobj,a[1]]=a[2];
    nstadef[nobj]=1;
    split(a[3],p,"");
    spat="";for(k=1;k<=10;k++){spat=spat""sprintf("%1i ",p[k])};
    pat3[nobj,a[1]]=spat;
    if(nw-3<npth[nobj]){
      emsg=FNR" Invalid path-status-3D definition.";
      exit;
    }
    psta3[nobj,a[1]]="";
    for(i=4;i<=nw;i++){psta3[nobj,a[1]]=psta3[nobj,a[1]]" "a[i]};
    old_style=1;
  }else{
    psta[nobj]=line;
    if(nw<npth[nobj]){
      emsg=FNR" Invalid path-status definition.";
      exit;
    }
  }
}
## old-style ORBITS / TH
$0~/^</&&objdefined{ #lines starting with "<"
  line=substr($0,2);
  nw=split(line,a);
  what="tham";
  if(nw>=6){
    t1=(a[1]>0&&a[1]<11); #words basis 1
    t2=(a[2]>0&&a[2]<11); #words basis 1
    tch=(a[5]>-1&&a[5]<110); # words chemistry
    if(t1&&t2&&tch){what="orbit"};
    old_style=1;
  };
#  print what,a[1],a[2] > STDE;
  if(what=="orbit"){
    orbdef=1;
    if(thdef){
      emsg=FNR": possibly mixing tile-hamiltonian and atom-orbit definitions.";
      exit;
    }
    sub_xy(a);
#    print a[3],a[4]>STDE;
    adef="";for(i=1;i<=6;i++){adef=adef" "a[i]};
    norb[nobj]++;
    orb[nobj,norb[nobj]]=adef;
    old_style=1;
  }else{ # TILEHAM
    if(orbdef){
      emsg=FNR": possibly mixing tile-hamiltonian and atom-orbit definitions.";
      exit;
    }
    thdef=1;
    ene[nobj]=a[1];
  }
}
## old-style OBJECTS
$0~/^=/{ #lines starting with "=" (objects)
  old_style=1;
  objdefined=1;
  line=substr($0,2);
  nobj++;
#  print "object "nobj > STDE # DEBUG
  nw=split(line,a);
  nu[nobj]=a[1];
  np=split(a[2],p,"");
  if(np!=10){
    emsg=FNR": Invalid pattern definition.";
  }
  pat[nobj]="";for(k=1;k<=10;k++){pat[nobj]=pat[nobj]p[k]" "};
  np=split(a[3],b,"");
  if(np!=10){
    emsg=FNR": Invalid basis definition.";
  }
  for(k=1;k<=10;k++){if(b[k]>0){b1=k}};
  np=split(a[4],b,"");
  if(np!=10){
    emsg=FNR": Invalid basis definition.";
  }
  for(k=1;k<=10;k++){if(b[k]>0){b2=k}};
  bas[nobj]=b1" "b2;
  npth[nobj]=a[5]; pth[nobj]=""; psta[nobj]="";
  for(k=1;k<=npth[nobj];k++){
    pth[nobj]=pth[nobj]" "a[5+k];
    psta[nobj]=psta[nobj]" 1";
  };
  oname[nobj]=a[5+npth[nobj]+1];
#  nsta[nobj,-1]=1;
#  nsta[nobj,1]=1;
}
ARGIND==colorfile{
  rgb[$2]=$3" "$4" "$5" rgb";
#  print rgb[$2] > STDE;
}
END{
#  print "xxxxx "ocolor[2] > "DEBUG";
#  print nobj_save,nobj,dbfile>STDE;
  if(query){print "DPmodel : ",dpmodel > STDE};
  deco=0;
  if(orbdef){deco=1};
#    if(thdef){deco=0};
  if(!dbfile){nobj_save=nobj};
  if(!emsg&&!nobj_save){emsg="Found no valid object definition"};
  if(!emsg){
    if(chdefs){
      printf "" > "INPUT/chps.def"; # erase chps.def
      for(sps in chps){
	split(chps[sps],a);
	match(chps[sps],/\{.*\}/);
#	print a[1],a[2],a[3] > STDE;
	ss="";
	if(RLENGTH>0){ss=substr(chps[sps],RSTART,RLENGTH)};
	if(!ss&&colorfile&&a[3]){
	  if(rgb[a[3]]){
	    ss="{"rgb[a[3]]"} # \""a[3]"\"";
	  }else{
	    ss="{} # couldnt find \""a[3]"\" in INPUT/FIG/colors.def";
	  }
	};
	if(!ss){ss="{}"};
	print a[1],a[2],ss >> "INPUT/chps.def";
      };
    };
    if(apsdefs){
      printf "" > "INPUT/orbps.def";
    }
    if(opsdefs){
#      print opsdefs" # object ps definitions" > "INPUT/objps.def";
      printf "" > "INPUT/objps.def"; # clear the file
      for(sps in ops){
	split(ops[sps],a);
	n=3; if(a[1]==2){n=4};
	ss="";
	sname="\""sps"\"";
	match(ops[sps],/\{.*\}/);
	if(RLENGTH>0){ss=substr(ops[sps],RSTART,RLENGTH)" "sname"  # def"};
#	  print sps,ops[sps],RSTART,RLENGTH,ss,ARGIND>STDE;
	if(!ss&&colorfile&&a[n]){
	  if(rgb[a[n]]){ss="{"rgb[a[n]]"} "sname" # _"a[n]"_"}else{
	    ss="{} "sname" # couldnt find _"a[n]"_ in INPUT/FIG/colors.def";
	  }
#	  print "COLOR ",n,a[n],rgb[a[n]],ss > STDE;
	};
	if(!ss){ss="{} "sname};
#	print "WORDS_OBJPS ","sps "sps,"ops "ops[sps],"ss "ss > STDE;
	if(n==3){printf "<%i %1.1f ",a[1],a[2] >> "INPUT/objps.def"};
	if(n==4){printf "<%i %i %1.1f ",a[1],a[2],a[3] >> "INPUT/objps.def"};
	print ss >> "INPUT/objps.def";
      };
    };
#    print n_obj_save "objsave " nobj_save > "DEBUG";
    for(i=1;i<=nobj_save;i++){
#      print i" obj "obj_name[i] > "DEBUG";
      if(copy[oname[i]]){
	j=name2i[copy[oname[i]]];
	if(!nu[i]){nu[i]=nu[j]};
	if(!nu2[i]){nu2[i]=nu2[j]};
	if(!bas[i]){bas[i]=bas[j]};
	if(!pat[i]){pat[i]=pat[j]};
	if(!npth[i]){
	  if(npth[j]){
	    npth[i]=npth[j];
	    pth[i]=pth[j];
	    if(psta[j]&&!psta[i]){psta[i]=psta[j]};
	  };
	};
# 3D
	for(l=-1;l<=1;l++){
	  if(l){
	    if(!nstadef[i]){nsta[i,l]=nsta[j,l]};
	    if(!pat3[i,l]){pat3[i,l]=pat3[j,l]};
	    if(psta3[j,l]&&!psta3[i,l]){psta3[i,l]=psta3[j,l]};
	  };
	};
      };
      if(!deco){
	if(!ene[i]){ene[i]=0.0};
	if(!tdfix[i]){tdfix[i]=0};
      };
      if(dpmodel==0){nu[i]=0};
      if(!nu[i]){nu[i]=0};
      if(!nu2[i]){nu2[i]=1};
      if(!bas[i]){bas[i]="1 3"};
      if(!pat[i]){pat[i]="2 2 2 2 2 2 2 2 2 2"};
      if(npth[i]&&!psta[i]){
	psta[i]="";for(k=1;k<=npth[i];k++){psta[i]=psta[i]"1 "}; # default
      };
    }; # end loop objects
    if(query&&!qq){
      if(!deco){
	print "OBJ    OBJECT_NAME NU  FLA   BAS NODE_PATTERN NPTH  3D NORB THENE" > STDE;
      }else{
	print "OBJ    OBJECT_NAME NU  FLA   BAS NODE_PATTERN NPTH  3D NORB OLABS" > STDE;
      };
	print "-----------------------------------1234567890--------------------">STDE;
    };
    if(!query){
      print deco," # 0=tile-ham; 1=atomic decoration; -1=undef";
      print def3d," # 3D extension";
      print nobj_save," # total objects #";
    };
#    print nobj_save" nobj_save "ocolor[2] >> "DEBUG";
    for(i=1;i<=nobj_save;i++){
      if(!fla[i]){fla[i]="0 0 0"};
      if(!npth[i]){npth[i]=0};
      if(!nipat[i]){nipat[i]=0};
      if(!ipthrec[i]){ipthrec[i]=0};
      if(!query){
	if(!nonu[i])nonu[i]=0;
	print oname[i];
	print nu2[i]," # root node instance, if != 1";
	print ocolor[i]," # user-defined colors associated with an object";
	print autocc[i]," # autocenter";
	print nu[i]," # nu discrete perp";
#	print nonu[i],onu[i]," # flip_node_instance";
	print fla[i]," # fla";
	print bas[i]," # basis";
	print nipat[i]," # pattern-instances";
	if(nipat[i]){
	  for(j=1;j<=nipat[i];j++){
	    printf "  "ipat[i,j];
	  }; print "";
	}
	print ipthrec[i]"  # in-boundary-instances";
	print pat[i]," # pattern";
	print npth[i]," ",pth[i]," ",psta[i]" # path";
#	print def3d,oname[i]>STDE;
	if(def3d){  # 3D object extension!
	  p3def=pat[i];
	  pst3def=psta[i];
	  nst=1;
	  if(init3d==2){
	    p3def="2 2 2 2 2 2 2 2 2 2";
	    pst3def="";
	    for(j=1;j<=npth[i];j++){pst3def=pst3def" 2"};
	    nst=2;
	  }
	  if(!nstadef[i]){
	    nsta[i,-1]=nst;
	    nsta[i,1]=nst;
	  };
	  if(!pat3[i,1]){pat3[i,1]=p3def};
	  if(!pat3[i,-1]){pat3[i,-1]=p3def};
	  if(npth[i]&&!psta3[i,1]){psta3[i,1]=pst3def};
	  if(npth[i]&&!psta3[i,-1]){psta3[i,-1]=pst3def};
	  print nsta[i,-1]," ",nsta[i,1]," # 3D node-status: height -+1";
	  print pat3[i,-1]," ",pat3[i,1]," # 3D pattern extension: height -+1";
	  if(npth[i]){print psta3[i,-1]," ",psta3[i,1]," # 3D path status: height -+1"};
	};
	if(!norb[i]){norb[i]=0};
	if(!deco){
	  print ene[i],tdfix[i],tdens[i]," # energy (opt fix_tile_density)";
	};
      }else{ #query
	if(!qq){#query q
	  if(nstadef[i]||pat3[i,1]||pat3[i,-1]){d3d="y"}else{d3d="-"};
	  if(norb[i]){dorb=norb[i]}else{dorb=0};
	  gsub(/ /,"",pat[i]);
#	gsub(/0/,"_",pat[i]);
#	gsub(/1/,"|",pat[i]);
#	gsub(/2/,"*",pat[i]);
	  gsub(/ /,"",fla[i]);
	  if(norb[i]){
	    o1=totorb+1;
	    o2=totorb+norb[i];
	    omsg=" ("o1"-"o2")";
	  }else{omsg="   --"};
#	  if(deco){
	    printf("%2i %15s %2i %4s  %4s   %10s %4i %3s %4i%s\n",i,oname[i],nu[i],fla[i],bas[i],pat[i],npth[i],d3d,dorb,omsg);
#	  }else{	    
#	    printf("%2i %15s %2i %4s    --   %10s %4i %3s %4i%6s\n",i,oname[i],nu[i],fla[i],pat[i],npth[i],d3d,dorb,ene[i]);
#	  };
	}else{ #query qq
	  if(qobj==oname[i]){#complete info about this object
	    if(pat3[i,1]||pat3[i,-1]){d3d="y"}else{d3d="-"};
	    gsub(/ /,"",pat[i]);
	    gsub(/ /,"",fla[i]);
	    if(npth[i]){
	      gsub(/ /,",",pth[i]);
	      gsub(/ /,"",psta[i]);
	    };
	    if(deco){
	      print oname[i]" "nu[i]"  "fla[i]"  "bas[i]"  "pat[i]"  "npth[i]" "pth[i]" "psta[i]}
	    else{
	      print oname[i]" "nu[i]"  "fla[i]"   --  "pat[i]"  "npth[i]" "pth[i]" "psta[i];
	    };
	  };
	  if(d3d=="y"){
	    printf "3D: ";
	    for(l=-1;l<=1;l++){
	      if(npth[i]&&!psta3[i,l]){psta3[i,l]=psta[i]};
	      if(l){
		gsub(/ /,"",pat3[i,l]);
		gsub(/ /,"",psta3[i,l]);
		printf "%s %s %s",nsta[i,l],pat3[i,l],psta3[i,l];
	      };
	    };
	    printf "\n";
	  };
	  if(norb[i]){
	    print totorb+j,norb[i]," # orbits";
	    for(j=1;j<=norb[i];j++){
	      if(!osb[i,j]){osb[i,j]=" 0"};
	      split(orb[i,j],a);
#		print totorb+j,orb[i,j]," ",osb[i,j];
	      printf "%2i %4i %2i %12.9f %12.9f %6.3f %3i %2i\n",totorb+j,a[1],a[2],a[3],a[4],a[5],a[6],osb[i,j];
	    };
	  };
	}; # if condition object query
      }; # query all, or particular object
      if(orbdef&&!query){
	print norb[i]," # orbits for "oname[i];
	for(j=1;j<=norb[i];j++){
	  if(!osb[i,j]){osb[i,j]=" 0 "};
          print orb[i,j],orbclass[i,j]," ",osb[i,j];
	  if(apsdefs&&aps[i,j]){
#	    print "APS ",i,j,totorb,aps[i,j] > STDE;
	    split(aps[i,j],a);
	    ss="";
	    match(aps[i,j],/\{.*\}/);
	    if(RLENGTH>0){ss=substr(aps[i,j],RSTART,RLENGTH)};
	    if(!ss&&colorfile&&a[2]){
	      if(rgb[a[2]]){ss="{"rgb[a[2]]"} # \""a[2]"\""}else{
		ss="{} # couldnt find \""a[2]"\" in INPUT/FIG/colors.def";
	      };
	    };
	    if(!ss){ss="{}"};
	    print totorb+j,a[1],ss >> "INPUT/orbps.def";
	  };
	};
      };
      totorb+=norb[i];
#      print i,"totorb ",totorb;
      if(!query){print "#------------- end "oname[i]" ----------------";}
    }; #end loop through objects
    if(query){
      if(old_style&&new_style){
	print "Decofile with mixed old-style and new-style convention." > STDE;
      }
      if(old_style&&!new_style){
	print "Decofile using old-style conventions (with = < + ... line prefixes)." > STDE;
      }
    }
  }else{
    print emsg > STDE;
  }# end if emsg
  fn="INPUT/onames.def";
  for(i=1;i<=ntorb;i++){
    print i,orbname[i]> fn;
  }
}

############# functions ##########################################

function sub_xy(a){
  number = "^[+-]?([0-9]+[.]?[0-9]*|[.][0-9]+)$"; # dont handle exp etc
  nonumber = "[a-z]|[A-Z]|\\*|\\/";
  for(i=3;i<=5;i++){
    if(a[i] ~ nonumber){ # this is an expression; handled by bc
# use the "two-way" pipe
      cmd="bc -q -l .bcinp";
      print a[i] |& cmd;
#      flush(cmd);
      cmd |& getline temp;
#      print "DBG "a[i],temp>STDE;
      a[i]=sprintf("%1.11f",temp);
#### old way using linefile .bcout
#      system("echo "a[i]" | bc -q -l .bcinp>>.bcout");
#      getline a[i] < ".bcout";
#      close(".bcout");
      if(a[i] !~ number){
	print "Warning: const "a[i]" was not interpreted correctly">STDE;
      }
    }
  }
  return;
}

function inst(x){
  if(tolower(x)=="x"){return instdef} else {return x};
}

function specie(x){
  if(x!~/[[:digit:]]/){ # this should be specie definition by element name
#    printf "specie "x" -> " > STDE;
    x=chs[tolower(x)];
#     print x > STDE;
    if(x!~/[[:digit:]]/){
      print "Line "FNR" of decofile: dont understand chemical assignement of \""x"\"" >STDE;
    };
  }
  return x;
}
